﻿#include "util.h"
#include "design/styleDefine.h"
#include <QImageReader>
#include <QFile>
#include <QFileDialog>
#include <fstream>
#include <regex>

bool FileExist(const QString &strFileName)
{
    QFile file(strFileName);
    return file.exists();
}

// [C++] 以二进制方式从文件中读取数据
bool ReadFileByBinary(const std::string &strFile, std::string &strContext)
{
    bool bRet = false;
    std::ifstream inputStream;
    do
    {
        strContext.clear();
        if(strFile.empty())
        {
            break;
        }

        inputStream.open(strFile, std::ios::in | std::ios::binary);
        if(!inputStream.is_open())
        {
            break;
        }

        const std::string text((std::istreambuf_iterator<char>(inputStream)), (std::istreambuf_iterator<char>()));
        strContext.assign(text);

        bRet = true;
    }while(0);

    if(inputStream.is_open())
    {
        inputStream.close();
    }

    return bRet;
}

QPushButton* NewPTBWithIcon(const QString& strTitle, const QString& strTip, const QIcon& icon, QWidget* parent)
{
    QPushButton* pPTB = new QPushButton(parent);
    if(nullptr != pPTB)
    {
        pPTB->setStyleSheet("QPushButton { border: none; background-color: transparent; }");
        pPTB->setFixedWidth(OBJ_FIXED_WIDTH_NORMAL);
        pPTB->setText(strTitle);
        //pPTB->setToolTip(strTip);
        pPTB->setStatusTip(strTip);
        pPTB->setFlat(true);
        pPTB->setIcon(icon);
    }

    return pPTB;
}

// 校验字符串是否包含有效数字
bool checkValidNumber(const QString& strSrc)
{
    if(strSrc.isEmpty())
    {
       return false;
    }
    /*
    for(auto &it : strSrc)
    {
        if(!(it >= '0' && it <= '9'))
        {
            return false;
        }
    }

    return true;*/
    std::regex strValidip("^[+|-]?(([0-9]+\\.[0-9]*)|([0-9]*\\.[0-9]+)|([0-9]+))([e|E][+|-]?[0-9]+)?$");
    if (!regex_match(strSrc.toStdString(), strValidip))
    {
        return false;
    }

    return true;
}

// 根据限定范围进行校验
void checkNumWithRange(uint& iNum, const uint iMin, const uint iMax)
{
    if(iNum < iMin)
    {
        iNum = iMin;
    }
    else if(iNum > iMax)
    {
        iNum = iMax;
    }
}

// 根据真实坐标值在图片上画框
bool picDrawRectLocation(QImage &pImg, const IMG_RECT_INT &stRect, const QRgb pColour, const uint pSize)
{
    if(pImg.isNull())
    {
        return false;
    }

    uint iImgWidth = pImg.width();
    uint iImgHeight = pImg.height();
    uint iLeftUpX = stRect.iX;
    uint iLeftUpY = stRect.iY;
    uint iRightDownX = stRect.iX + stRect.iWidth;
    uint iRightDownY = stRect.iY + stRect.iHeight;
    checkNumWithRange(iLeftUpX, 0, iImgWidth);
    checkNumWithRange(iLeftUpY, 0, iImgHeight);
    checkNumWithRange(iRightDownX, 0, iImgWidth);
    checkNumWithRange(iRightDownY, 0, iImgHeight);

    for(uint idx = 0; idx < iImgWidth; idx++)
    {
        for(uint idy = 0; idy < iImgHeight; idy++)
        {
            if((idx >= (iLeftUpX - pSize) && idx <= (iLeftUpX + pSize)) ||
               (idx >= (iRightDownX - pSize) && idx <= (iRightDownX + pSize)))
            {
                if(idy >= (iLeftUpY - pSize) && idy <= (iRightDownY + pSize))
                {
                    pImg.setPixelColor(idx, idy, pColour);
                }
            }
            else if((idy >= (iLeftUpY - pSize) && idy <= (iLeftUpY + pSize)) ||
                    (idy >= (iRightDownY - pSize) && idy <= (iRightDownY + pSize)))
            {
                if(idx >= (iLeftUpX - pSize) && idx <= (iRightDownX + pSize))
                {
                    pImg.setPixelColor(idx, idy, pColour);
                }
            }
        }
    }

    return true;
}

// 根据归一化坐标值在图片上画框
bool picDrawRectNormalization(QImage& pImg, const IMG_RECT_FLOAT& stRect, const QRgb pColour, const uint pSize)
{
    if(pImg.isNull())
    {
        return false;
    }

    uint iImgWidth = pImg.width();
    uint iImgHeight = pImg.height();
    IMG_RECT_INT stRectInt;
    stRectInt.iX = iImgWidth * stRect.fX;
    stRectInt.iY = iImgHeight * stRect.fY;
    stRectInt.iWidth = iImgWidth * stRect.fWidth;
    stRectInt.iHeight = iImgHeight * stRect.fHeight;

    return picDrawRectLocation(pImg, stRectInt, pColour, pSize);
}

// 根据路径获取图片数据
bool getImgFromPath(QImage &pImg, const QString& strPath)
{
    bool bStatus = true;
    QImageReader pReader(strPath);
    pReader.setDecideFormatFromContent(true);
    bStatus = pReader.canRead();
    if(true == bStatus)
    {
        bStatus = pReader.read(&pImg);
    }

    return bStatus;
}

// 根据路径提取文件格式，以.为依据
QString getFormatFromFile(const QString& strPath)
{
    QString strFormat;

    std::string str = strPath.toStdString();
    std::string::size_type itPos = str.find_last_of('.');
    if(std::string::npos != itPos)
    {
        std::string strSub = str.substr(itPos + 1, str.length() - itPos - 1);
        strFormat = QString::fromStdString(strSub);
    }

    return strFormat;
}

// 打开文件窗口，并选取指定文件
QString GetFileFromFileDialog(QWidget *parent, const QString &strFileParam)
{
    QString curPath = QCoreApplication::applicationDirPath(); //获取应用程序的路径

    //调用打开文件对话框打开一个文件
    return QFileDialog::getOpenFileName(parent, QString("打开文件"), curPath, strFileParam);
}

// 根据状态值确认界面展示或关闭
void DialogShowAndHide(const bool bStatus, QWidget* pDialog)
{
    if (nullptr != pDialog)
    {
        if (true == bStatus)
        {
            pDialog->show();
        }
        else
        {
            pDialog->hide();
        }
    }
}